/* TMLNXD.C
 * Copyright (c) 2007 MissingNODE 
 * Based on GPL OpenQM Code
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * 
 * 
 * START-HISTORY:
 * Oct-10-2007 Initial Revision
 * END-HISTORY
 *
 * START-DESCRIPTION:
 *
 * END-DESCRIPTION
 *
 * START-CODE
 */

#define public
#define init(a) = a
#include <tm.h>

#include <time.h>
#include <ctype.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>

int shmid;   /* Shared memory id */

bool terminate = FALSE;

void check_lost_users(void);

void signal_handler(int signum);

/* ====================================================================== */

int main()
{
 char errmsg[80];
 int timer = 0;

 signal(SIGTERM, signal_handler);

 /* Attach the shared memory segment */

 if (((shmid = shmget(TM_SHM_KEY, 0, 0666)) == -1)
    || (((int)(sysseg = (SYSSEG *)shmat(shmid, NULL, 0))) == -1))
  {
   exit(1);
  }

 /* Get access to semaphores */

 if (!get_semaphores(FALSE, errmsg)) exit(2);


 /* ========================= Main loop ========================= */


 while(!terminate)
  {
   timer++;

   /* One minute actions */


   if ((timer % 5) == 0)
    {
     /* Five minute actions */

     check_lost_users();
    }

   sleep(60);
  }


 /* Tidy up on our way out */

 shmdt((void *)sysseg);   /* Dettach shared memory */

 return 0;
}

/* ======================================================================
   check_lost_users()  -  Clear down "lost" processes                     */

void check_lost_users()
{
 USER_ENTRY * uptr;
 long int pid;
 short int u;
 bool lost_user_detected = FALSE;
 char cmd[MAX_PATHNAME_LEN+10];

 StartExclusive(SHORT_CODE,69);

 for (u = 1; u <= sysseg->max_users; u++)
  {
   uptr = UPtr(u);
   pid = uptr->pid;
   if (uptr->uid)
    {
     if (kill(pid, 0) && (errno != EPERM))
      {
       lost_user_detected = TRUE;
       break;
      }
    }
  }

 EndExclusive(SHORT_CODE);

 if (lost_user_detected)
  {
   /* Fire off a TM session to clear down the users. Although it would be
      nice to do the whole job here, there are so many dependencies that
      tmlnxd ends up carrying around most of TM.                          */

   sprintf(cmd, "%s/bin/tm -cleanup", sysseg->sysdir);
   system(cmd);
  }
}


/* ======================================================================
   Signal handler                                                         */

void signal_handler(signum)
   int signum;
{
 switch(signum)
  {
   case SIGTERM:
      signal(SIGTERM, SIG_IGN);
      terminate = TRUE;
      break;
  }
}

/* END-CODE */
